package com.scut.shangxueguan.service.Impl;

import com.scut.shangxueguan.constant.AdministratorConstant;
import com.scut.shangxueguan.mapper.AdministratorMapper;
import com.scut.shangxueguan.pojo.Administrator;
import com.scut.shangxueguan.pojo.Result;
import com.scut.shangxueguan.service.IAdministratorService;
import com.scut.shangxueguan.utils.JwtUtil;
import com.scut.shangxueguan.utils.MD5Util;
import com.scut.shangxueguan.utils.ThreadLocalUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class AdministratorServiceImpl implements IAdministratorService {

    private final AdministratorMapper administratorMapper;

    private final StringRedisTemplate stringRedisTemplate;

    // token过期时间
    private static final long EXPIRE_TIME = 1000 * 60 * 60 * 12;

    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public Result<String> login(String username, String password) {
        Administrator administrator = administratorMapper.selectByUsername(username);
        if(administrator == null){
            // TODO 修改为用户名或密码错误
            return Result.error("用户名错误！");
        }

        if(!MD5Util.verify(password,administrator.getPassword())){
            // TODO 修改为用户名或密码错误
            return Result.error("密码错误！");
        }

        Map<String, Object> claims = new HashMap<>();
        long id = administrator.getId();
        claims.put("id", id);
        claims.put("username", username);
        String token = JwtUtil.getToken(claims, EXPIRE_TIME);

        // 利用白名单机制，保存用户的token令牌
        // 用用户id作为key，只能保证只有一个用户在使用
        stringRedisTemplate.opsForValue().set(AdministratorConstant.LOGIN_KEY + String.valueOf(id), token,
                EXPIRE_TIME, TimeUnit.MILLISECONDS);

        return Result.success(token);
    }

    @Override
    public Result updatePassword(String oldPassword, String newPassword, String renewPassword) {
        long id = Long.parseLong(ThreadLocalUtil.get("id", 0).toString());
        Administrator administrator = administratorMapper.selectById(id);

        if(administrator == null || !MD5Util.verify(oldPassword, administrator.getPassword())){
            return Result.error("原密码错误！");
        }

        if (!newPassword.equals(renewPassword)){
            return Result.error("两个密码不一致");
        }

        administratorMapper.updatePasswordById(id, MD5Util.generateMD5(newPassword));
        stringRedisTemplate.delete(AdministratorConstant.LOGIN_KEY + String.valueOf(id));
        return Result.success();
    }

    @Override
    public Result logout() {
        long id = Long.parseLong(ThreadLocalUtil.get("id", 0).toString());
        stringRedisTemplate.delete(AdministratorConstant.LOGIN_KEY + String.valueOf(id));
        return Result.success();
    }
}
